package com.myproject.utils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串处理工具类
 * 
 * <p>封装常用的字符串操作方法，基于Java标准库实现。</p>
 */
public class StringUtils extends org.apache.commons.lang3.StringUtils{

    private StringUtils() {
        // 私有构造方法防止实例化
    }

    // ------------------- 判空操作 -------------------

    /**
     * 判断字符串是否为null或空字符串
     * @param str 输入字符串
     * @return 如果为null或空字符串返回true，否则返回false
     */
    public static boolean isEmpty(CharSequence str) {
        return str == null || str.length() == 0;
    }

    /**
     * 判断字符串是否为非null且非空字符串
     * @param str 输入字符串
     * @return 如果为非null且非空字符串返回true，否则返回false
     */
    public static boolean isNotEmpty(CharSequence str) {
        return !isEmpty(str);
    }

    /**
     * 判断字符串是否为空白字符串（null、空字符串或仅包含空白字符）
     * @param str 输入字符串
     * @return 如果为空白字符串返回true，否则返回false
     */
    public static boolean isBlank(CharSequence str) {
        if (isEmpty(str)) {
            return true;
        }
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符串是否为非空白字符串（非null、非空字符串且不全是空白字符）
     * @param str 输入字符串
     * @return 如果为非空白字符串返回true，否则返回false
     */
    public static boolean isNotBlank(CharSequence str) {
        return !isBlank(str);
    }

    // ------------------- 字符串格式化 -------------------

    /**
     * 格式化字符串（使用%s占位符）
     * @param format 格式字符串
     * @param args 参数
     * @return 格式化后的字符串
     */
    public static String format(String format, Object... args) {
        return args == null || args.length == 0 ? format : String.format(format, args);
    }

    /**
     * 去除字符串两端的空白字符
     * @param str 输入字符串
     * @return 去除两端空白后的字符串
     */
    public static String trim(String str) {
        return str == null ? null : str.trim();
    }

    /**
     * 去除字符串中的所有空白字符
     * @param str 输入字符串
     * @return 去除所有空白后的字符串
     */
    public static String trimAll(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.replaceAll("\\s+", "");
    }

    // ------------------- 字符串截取 -------------------

    /**
     * 截取字符串
     * @param str 输入字符串
     * @param start 开始位置（包含）
     * @return 截取后的字符串
     */
    public static String substring(String str, int start) {
        if (str == null) {
            return null;
        }
        if (start < 0) {
            start = str.length() + start;
        }
        if (start < 0) {
            start = 0;
        }
        return start > str.length() ? "" : str.substring(start);
    }

    /**
     * 截取字符串
     * @param str 输入字符串
     * @param start 开始位置（包含）
     * @param end 结束位置（不包含）
     * @return 截取后的字符串
     */
    public static String substring(String str, int start, int end) {
        if (str == null) {
            return null;
        }
        if (end < 0) {
            end = str.length() + end;
        }
        if (start < 0) {
            start = str.length() + start;
        }
        if (end > str.length()) {
            end = str.length();
        }
        if (start > end) {
            return "";
        }
        if (start < 0) {
            start = 0;
        }
        if (end < 0) {
            end = 0;
        }
        return str.substring(start, end);
    }

    /**
     * 截取字符串，如果超过最大长度则添加省略号
     * @param str 输入字符串
     * @param maxLength 最大长度
     * @return 截取后的字符串
     */
    public static String abbreviate(String str, int maxLength) {
        if (isEmpty(str) || str.length() <= maxLength) {
            return str;
        }
        return str.substring(0, maxLength) + "...";
    }

    // ------------------- 字符串转换 -------------------

    /**
     * 将字符串转换为大写
     * @param str 输入字符串
     * @return 大写字符串
     */
    public static String toUpperCase(String str) {
        return str == null ? null : str.toUpperCase();
    }

    /**
     * 将字符串转换为小写
     * @param str 输入字符串
     * @return 小写字符串
     */
    public static String toLowerCase(String str) {
        return str == null ? null : str.toLowerCase();
    }

    /**
     * 将字符串首字母大写
     * @param str 输入字符串
     * @return 首字母大写的字符串
     */
    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 将字符串首字母小写
     * @param str 输入字符串
     * @return 首字母小写的字符串
     */
    public static String uncapitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }

    /**
     * 将字符串转换为UTF-8字节数组
     * @param str 输入字符串
     * @return UTF-8字节数组
     */
    public static byte[] getBytesUtf8(String str) {
        return str == null ? null : str.getBytes(StandardCharsets.UTF_8);
    }

    /**
     * 将UTF-8字节数组转换为字符串
     * @param bytes 字节数组
     * @return 字符串
     */
    public static String newStringUtf8(byte[] bytes) {
        return bytes == null ? null : new String(bytes, StandardCharsets.UTF_8);
    }

    // ------------------- 字符串匹配 -------------------

    /**
     * 判断字符串是否匹配正则表达式
     * @param str 输入字符串
     * @param regex 正则表达式
     * @return 如果匹配返回true，否则返回false
     */
    public static boolean matches(String str, String regex) {
        if (str == null || regex == null) {
            return false;
        }
        return str.matches(regex);
    }

    /**
     * 使用正则表达式提取匹配的字符串
     * @param str 输入字符串
     * @param regex 正则表达式
     * @return 匹配的字符串列表
     */
    public static List<String> extractMatches(String str, String regex) {
        List<String> matches = new ArrayList<>();
        if (isEmpty(str) || isEmpty(regex)) {
            return matches;
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            matches.add(matcher.group());
        }
        return matches;
    }

    // ------------------- 字符串加密/解密 -------------------

    /**
     * 简单的字符串加密（Base64编码）
     * @param str 输入字符串
     * @return Base64编码后的字符串
     */
    public static String encodeBase64(String str) {
        return str == null ? null : java.util.Base64.getEncoder().encodeToString(getBytesUtf8(str));
    }

    /**
     * 简单的字符串解密（Base64解码）
     * @param str Base64编码的字符串
     * @return 解码后的字符串
     */
    public static String decodeBase64(String str) {
        return str == null ? null : newStringUtf8(java.util.Base64.getDecoder().decode(str));
    }

    // ------------------- 字符串拼接/分割 -------------------

    /**
     * 使用分隔符连接字符串数组
     * @param delimiter 分隔符
     * @param elements 字符串数组
     * @return 连接后的字符串
     */
    public static String join(CharSequence delimiter, CharSequence... elements) {
        if (elements == null || elements.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < elements.length; i++) {
            if (i > 0) {
                sb.append(delimiter);
            }
            sb.append(elements[i]);
        }
        return sb.toString();
    }

    /**
     * 使用分隔符连接字符串集合
     * @param delimiter 分隔符
     * @param elements 字符串集合
     * @return 连接后的字符串
     */
    public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) {
        if (elements == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (CharSequence element : elements) {
            if (!first) {
                sb.append(delimiter);
            }
            sb.append(element);
            first = false;
        }
        return sb.toString();
    }

    /**
     * 分割字符串
     * @param str 输入字符串
     * @param delimiter 分隔符
     * @return 分割后的字符串数组
     */
    public static String[] split(String str, String delimiter) {
        if (isEmpty(str)) {
            return new String[0];
        }
        if (delimiter == null) {
            return new String[]{str};
        }
        return str.split(Pattern.quote(delimiter));
    }

    // ------------------- HTML/XML转义 -------------------

    /**
     * 转义HTML特殊字符
     * @param str 输入字符串
     * @return 转义后的字符串
     */
    public static String escapeHtml(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\"", "&quot;")
                .replace("'", "&#39;");
    }

    /**
     * 反转义HTML特殊字符
     * @param str 输入字符串
     * @return 反转义后的字符串
     */
    public static String unescapeHtml(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.replace("&amp;", "&")
                .replace("&lt;", "<")
                .replace("&gt;", ">")
                .replace("&quot;", "\"")
                .replace("&#39;", "'");
    }

    /**
     * 转义XML特殊字符
     * @param str 输入字符串
     * @return 转义后的字符串
     */
    public static String escapeXml(String str) {
        return escapeHtml(str); // XML和HTML转义规则相同
    }

    /**
     * 反转义XML特殊字符
     * @param str 输入字符串
     * @return 反转义后的字符串
     */
    public static String unescapeXml(String str) {
        return unescapeHtml(str); // XML和HTML反转义规则相同
    }
}